<template>
  <div style="width: 100%;
    height: 100%;
    overflow: hidden;
    position: relative;">
    <div :id="domId" ref="refMapView" style="height: 100%;width: 100%;position: absolute;"></div>
    <SearchPanel v-if="searchPanel" :top="searchTop" :left="searchLeft" @change="locationQuery" />
  </div>
  </template>
  
  <script setup>
  import { onMounted, watch } from 'vue';
  import { useUserStore } from '@/pinia/modules/user'
  import mapboxgl from 'mapbox-gl'
  import SearchPanel from './components/SearchPanel.vue';
import postionIocn from './images/location-icon.png'
const userStore = useUserStore()
const emit = defineEmits([
  'onInit',
  'onDrag',
  'onDragEnd', 
  'onZoom',
  'onZoomEnd'
])
const mapboxtoken ="pk.eyJ1IjoiYnJpdHRhbnl5ZWUiLCJhIjoiY2p1ZTdpN3M4MDBlMzQ0bHJhaDh1b203ZyJ9.Kv9ykdRmPx5utrcMAY9uCg";
const tdttoken = "4cc66d27a3ef65764e7a58096e89aaf2";
let mapView= null
const props = defineProps({
  domId:{
    type:String,
    default:'map-container-view'
  }, 
  location:{
    type:Object,
    default:{
      latitude:0,
      longitude:0
    }
  },
  searchPanel:{
    type:Boolean,
    default:true
  },
  searchTop:{
    type:String,
    default:'10px'
  },
  searchLeft:{
    type:String,
    default:'320px'
  },
  loadingLand:{
    type:Boolean,
    default:true
  }
})

watch(()=>props.location,()=>{
  //跳转代码
  // mapView.jumpTo({
  //   center: [props.location.longitude, props.location.latitude],
  //   zoom: 18,
  //   // pitch: 45,
  //   // bearing: 90 
  // })

  //飞到代码
  mapView.flyTo({
    center: [props.location.longitude, props.location.latitude],
    zoom: 18,
    // speed: 0.2,
    // curve: 1,
    // easing(t) {return t;}
  })
})


  onMounted( ()=>{
    initMap()  
  })

  //初始化地图
  const initMap =()=>{
      let info ={ locationLongitude:106.45, locationLatitude:29.56}
      if(userStore.userInfo?.farmList){
        info = userStore.userInfo?.farmList?.find((item)=>item.farmId==userStore.userInfo.farmId)
      }
      mapboxgl.accessToken = mapboxtoken; 
      mapView = new mapboxgl.Map({
          container: props.domId,
          center: [Number(info.locationLongitude), Number(info.locationLatitude)],
          zoom: 12,
          style: "mapbox://styles/mapbox/satellite-v9",
          minzoom:8,
          maxzoom:20
          //  pitch: 45, // 地图倾斜角度
          //  bearing: -17.6, // 地图旋转角度
        });
        // mapView.setStyle('mapbox://styles/mapbox/dark-v9');
        mapView.on('load',()=> {
          addImageLayer()
          //初始化成功事件
          emit('onInit',mapView)
          //拖动事件
          mapView.on('drag', (e)=>{
            emit('onDrag',e)
          })
          mapView.on('dragend', (e)=>{
            emit('onDragEnd',e)
          })
          //放大缩小事件
          mapView.on('zoom', (e)=>{
            let currentZoom = Number(mapView.getZoom().toFixed(0));
            emit('onZoom',{...e,currentZoom:currentZoom})
          })
          mapView.on('zoomend', (e)=>{
            let currentZoom = Number(mapView.getZoom().toFixed(0));
            emit('onZoomEnd',{...e,currentZoom:currentZoom})
          })
      })
  }
  //添加图层配置
  const addImageLayer=()=>{

      // 天地图影像图层
      //  const tdt_url ="https://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=";
      //   mapView.addSource("tdt-source", {
      //     type: "raster",
      //     tiles: [tdt_url + tdttoken],
      //     tileSize: 256,
      //   });
      //   mapView.addLayer({
      //     id: "tdt-layer",
      //     type: "raster",
      //     source: "tdt-source",
      // });
        // mapView.setLayoutProperty('poi-label', 'visibility', 'none');
        // 添加天地图的 cia_w 图层
      // WMTS图层样式
     

    let geoserverLayerStyle = {
          "id": "geoserver-wmts",
          "type": "raster",
          "source": {
              "type": "raster",
              "tiles": [
                  "https://geo.cqtancheng.com/gwc/service/wmts?" +
                  "REQUEST=GetTile&VERSION=1.0.0&LAYER=layerGroups&STYLE=default&Format=image/png" +
                  "&TILEMATRIXSET=WebMercatorQuad&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}"
              ],
              "tileSize": 256
          },
          "minzoom": 8,
          "maxzoom": 22
      };
      mapView.addLayer(geoserverLayerStyle);


      //公司的wms服务
        // mapView.addSource("wms-test-source", {
        //   type: "raster",
        //   tiles: [ "https://geo.liaoliaofarm.com/geoserver/onemap/wms?bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&transparent=true&width=256&height=256&layers=baseImageLayerGroup",],
        //   tileSize: 256,
        // });
        // mapView.addLayer({
        //   id: "wms-test-layer",
        //   type: "raster",
        //   source: "wms-test-source",
        //   minzoom: 8,
        //   maxzoom: 22,
        //   paint: {},
        // });

        //中文标注
         mapView.addSource('cia_w', {
              type: 'raster',
              tiles: ['https://t0.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk='+tdttoken],
              tileSize: 256
          });
          mapView.addLayer({
              id: 'cia_w-layer',
              type: 'raster',
              source: 'cia_w',
              minzoom: 8,
              maxzoom: 22
          });
          //添加坐标图片
          mapView.loadImage(postionIocn,(error, image)=> {
            if (error) throw error; 
            mapView.addImage('martk-icon', image)
         })
  }

const getWindXY=(lng,lat)=>{
    if(lng && lat){ 
        const point = mapView.project(new mapboxgl.LngLat(Number(lng), Number(lat)))
        return {top:point.y,left:point.x}
    }else{
        return {top:0,left:0}
    }
  }

  
// 计算所有点的边界
const locationCenter =(points)=>{
  if(points.length<=0){return false}
  let bounds = points.reduce((bounds, point)=> {
    return bounds.extend(point);
  }, new mapboxgl.LngLatBounds(points[0], points[0]));
  
  mapView.jumpTo({ center: bounds.getCenter() });
  mapView.fitBounds(bounds, {
    padding: { top: 20, bottom: 20, left: 20, right: 20 }
  })
}

//检验layers图层是否存在
const doesLayerExist=(layerId)=> {
    const layers = mapView.getStyle().layers;
    return layers.find(layer => layer.id === layerId) !== undefined;
}

const addMartkSourceData =(coordinates)=>{
         mapView.addSource('martk-source', {
            type: 'geojson',
            data: {
                type: 'FeatureCollection',
                features:  [{
                        type: "Feature",
                        geometry: {
                            type: "Point",
                            coordinates: coordinates
                        }
                    }]
            }
    })
}

//搜索经纬度
const locationQuery =async (item)=>{
  let coordinates = [item.longitude, item.latitude]
  if(doesLayerExist('points-martk-icon')){
      mapView.getSource('martk-source').setData({
        type: 'FeatureCollection',
        features:[{
         type: "Feature",
          geometry: {
            type: "Point",
            coordinates: coordinates
          }
       }]});
  }else{
      addMartkSourceData(coordinates)
        mapView.addLayer({
          id: "points-martk-icon",
          type: "symbol",
          source:'martk-source',
          layout: {"icon-image": "martk-icon", "icon-size": 1}
      })
  }
    mapView.flyTo({ center: coordinates,zoom: 16})
}
 

// 计算多边形重心的函数
const calculateCentroid=(coordinates)=> {
  let signedArea = 0.0;
    let centroidX = 0.0;
    let centroidY = 0.0;
    let lastX, lastY;
 
    for (let i = 0, j = coordinates.length - 1; i < coordinates.length; j = i++) {
        let x = coordinates[i][0];
        let y = coordinates[i][1];
        let nextX = coordinates[j][0];
        let nextY = coordinates[j][1];
 
        let deltaX = nextX - x;
        let deltaY = nextY - y;
 
        signedArea += deltaX * (nextY + y);
 
        centroidX += (x + nextX) * (deltaX * deltaX + deltaY * deltaY) / 6.0;
        centroidY += (y + nextY) * (deltaX * deltaX + deltaY * deltaY) / 6.0;
    }
 
    signedArea *= -0.5;
    centroidX /= signedArea;
    centroidY /= signedArea;
 
    return [centroidX, centroidY];
}
 

defineExpose({
  getWindXY,
  locationCenter,
  calculateCentroid
})
  </script>
